package cn.catsdad.service.impl;

import cn.catsdad.base.page.PageBean;
import cn.catsdad.base.page.PageParam;
import cn.catsdad.base.service.impl.BaseCrudServiceImpl;
import cn.catsdad.dto.NoticeDTO;
import cn.catsdad.dto.NotifierDTO;
import cn.catsdad.dto.UserDTO;
import cn.catsdad.repository.NoticeRepository;
import cn.catsdad.service.api.NoticeService;
import cn.catsdad.service.api.NotifierService;
import cn.catsdad.service.api.UserService;
import cn.catsdad.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 通知service实现
 *
 * @author xuyonglong
 * @version V1.0 2023/5/11
 */
@Service
public class NoticeServiceImpl extends BaseCrudServiceImpl<NoticeDTO, Long, NoticeRepository> implements NoticeService {

    private NotifierService notifierService;
    private UserService userService;

    @Override
    public void pageQuery(PageBean<NoticeDTO> page, PageParam param) {
        page.setEntityName("DtoNotice n").setQuery("select n");
        super.pageQuery(page, param);
        loadTransientFields(page.getQueryResult());
    }

    @Override
    @Transactional
    public NoticeDTO save(NoticeDTO entity) {
        saveNotifiers(entity);
        return super.save(entity);
    }

    @Override
    @Transactional
    public NoticeDTO update(NoticeDTO entity) {
        saveNotifiers(entity);
        super.update(entity);
        return entity;
    }

    @Override
    public NoticeDTO queryById(Long aLong) {
        NoticeDTO result = super.queryById(aLong);
        loadTransientFields(Collections.singleton(result));
        return result;
    }

    /**
     * 填充临时字段
     *
     * @param entities 实体集合
     */
    @Override
    protected void loadTransientFields(Collection<NoticeDTO> entities) {
        Set<Long> creatorIds = new HashSet<>();
        List<Long> ids = new ArrayList<>(entities.size());
        entities.forEach(e -> {
            creatorIds.add(e.getCreatorId());
            ids.add(e.getId());
        });
        Map<Long, UserDTO> userMap = userService.queryMap(creatorIds);
        Map<Long, List<NotifierDTO>> notifierMap = notifierService.queryByNoticeIds(ids);
        for (NoticeDTO entity : entities) {
            List<Long> notifiers = notifierMap.get(entity.getId()) == null ? new ArrayList<>() :
                    notifierMap.get(entity.getId()).stream().map(NotifierDTO::getUserId).distinct().collect(Collectors.toList());
            entity.setNotifierIds(notifiers);
            UserDTO user = userMap.get(entity.getCreatorId());
            entity.setCreatorName(user == null ? "" : user.getUserName());
        }
    }

    /**
     * 保存通知人数据
     *
     * @param notice 保存的实体
     */
    private void saveNotifiers(NoticeDTO notice) {
        List<Long> notifierIds = notice.getNotifierIds();
        notifierService.deleteByNoticeIds(Collections.singleton(notice.getId()));
        List<NotifierDTO> notifiers = new ArrayList<>();
        for (Long notifierId : notifierIds) {
            NotifierDTO notifier = new NotifierDTO();
            notifier.setNoticeId(notice.getId());
            notifier.setUserId(notifierId);
            notifiers.add(notifier);
        }
        if (StringUtil.isNotEmpty(notifiers)) {
            notifierService.saveAll(notifiers);
        }

    }

    @Override
    @Transactional
    public void logicDeleteByIds(Collection<Long> longs) {
        notifierService.deleteByNoticeIds(longs);
        super.logicDeleteByIds(longs);
    }

    @Autowired
    @Lazy
    public void setNotifierService(NotifierService notifierService) {
        this.notifierService = notifierService;
    }

    @Autowired
    @Lazy
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
